####################################
# IRC BOT AND LIBRARY BY THEHOLDER #
####################################

from irc import IRCBot, run_bot
import random
import os
import time
import sys
from datetime import datetime
import json


locks = []
activator = False
owner = ["yournick"]

staff = []
f = open("staff.txt", "r")
for name in f.readlines():
	if len(name.strip()) > 0:
		staff.append(name.strip())
print(str(len(staff))+" Staff members")

users = []
f = open("whitelist.txt", "r")
for name in f.readlines():
	if len(name.strip()) > 0:
		users.append(name.strip())
print(str(len(users))+" Whitelisted users")

dictionary = dict() #volatile... of course...

f = open("definitions.txt", "r") # read-only
for line in f.readlines():
        try:
                if len(line.strip())>0:
                        word, definition, name = json.loads(line.strip())
                        dictionary[word] = json.dumps([definition, name])
        except:
                print("[ERR]Cant load definition: %s" % line)
f.close()
print("\033[94m[INF]\033[0mLoading %s Definitions..." % len(dictionary))

def uptime():
 
     try:
         f = open( "/proc/uptime" )
         contents = f.read().split()
         f.close()
     except:
        return "Cannot open uptime file: /proc/uptime"
 
     total_seconds = float(contents[0])
 
     # Helper vars:
     MINUTE  = 60
     HOUR    = MINUTE * 60
     DAY     = HOUR * 24
 
     # Get the days, hours, etc:
     days    = int( total_seconds / DAY )
     hours   = int( ( total_seconds % DAY ) / HOUR )
     minutes = int( ( total_seconds % HOUR ) / MINUTE )
     seconds = int( total_seconds % MINUTE )
 
     # Build up the pretty string (like this: "N days, N hours, N minutes, N seconds")
     string = ""
     if days > 0:
         string += str(days) + " " + (days == 1 and "day" or "days" ) + ", "
     if len(string) > 0 or hours > 0:
         string += str(hours) + " " + (hours == 1 and "hour" or "hours" ) + ", "
     if len(string) > 0 or minutes > 0:
         string += str(minutes) + " " + (minutes == 1 and "minute" or "minutes" ) + ", "
     string += str(seconds) + " " + (seconds == 1 and "second" or "seconds" )
 
     return string;
	 

class GreeterBot(IRCBot):
	global activator
	startTime = time.time()
	
	def getAccess(self, nick):
		if nick in owner: return 3
		if nick in staff: return 2
		if nick in users: return 1
		else: return 0
	
	def greet(self, nick, message, channel):
		if self.getAccess(nick.lower()) < 1:
			return
		else:
			return '%s %s' % (random.choice(["Herro", "Hi", "Hai", "Ohai"]), nick)
		
	def dice(self, nick, message, channel):
		if self.getAccess(nick.lower()) < 1:
			return
		else:
			return '%s rolls a dice a gets a %s ^-^' % (nick, random.randint(1, 6))
		
	def lock(self, nick, message, channel):
		if self.getAccess(nick.lower()) >= 2:
			locks.append(channel)
			return "k %s ^-^" % nick
		else:
			return "cant ^-^"
	
	def unlock(self, nick, message, channel):
		if self.getAccess(nick.lower()) >= 2:
			locks.remove(channel)
			return "k %s ^-^" % nick
		else:
			return "cant ^-^"
		
	def checklock(self, nick, message, channel):
		if channel in locks and self.getAccess(nick.lower()) >= 2:
			return "yep %s is locked ^-^" % channel
		if not channel in locks and self.getAccess(nick.lower()) >= 2:
			return "nope %s isn't locked ^-^" % channel
	
	def say(self, nick, message, channel):
		if self.getAccess(nick.lower()) < 1: 
			return
		else:
			return "%s ^-^" % message[4:]
		
	def aware(self, nick, message, channel):
		if self.getAccess(nick.lower()) < 1:
			return
		else:
			activator = True
			return "hmm %s?" % nick
	
	def sut(self, nick, message, channel):
		if self.getAccess(nick.lower()) < 1:
			return
		else:
			return "sys uptime: %s ^-^" % uptime()
	
	def sl(self, nick, message, channel):
		loads = ""
		l = os.getloadavg()
		loads += "(%s)  " % str(l[0])
		loads += "%s  " % str(l[1])
		loads += "%s " % str(l[2])
		if self.getAccess(nick.lower()) < 1:
			return
		else:
			return "Current Server Loads: %s ^-^" % loads
		
	def lvl(self, nick, message, channel):
		return "%s you are level %s ^-^" % (nick, self.getAccess(nick.lower()))
	
	def sd(self, nick, message, channel):
		if self.getAccess(nick) >= 3:
			sys.exit()
			
		if self.getAccess(nick) <= 1: 
			return "No :|"
			
	def wlcount(self, nick, message, channel):
		if self.getAccess(nick.lower()) < 2 and len(users) > 10:
			return "cant show you ^-^"
		else:	
			return "I have %s whitelisted users %s" % (len(users), ",".join(users))
	
	def wl(self, nick, message, channel):
		args = message[4:]
		if self.getAccess(nick.lower()) < 1:
			return
		else:
			if args in users: return "%s is already whitelisted ^-^" % args
			if self.getAccess(nick.lower()) < 2:
				return "%s your not allowed to whitelist %s ^-^" % (nick, args)
			else:
				users.append(args)
				f = open("whitelist.txt", "w")
				f.write("\n".join(users))
				f.close()
				return "%s %s has been whitelisted" % (nick, args)
			
	def staff(self, nick, message, channel):
		args = message[6:]
		if self.getAccess(nick.lower()) < 1:
			return
		else:
			if args in staff: return "%s is already a staff member" % args
			if self.getAccess(nick.lower()) < 3: 
				return "%s you cant add %s to my staff ^-^" % (nick,args)
			else:
				staff.append(args)
				f = open("staff.txt", "w")
				f.write("\n".join(staff))
				f.close()
				return "%s is now staff ^-^" % args
			
	def ut(self, nick, message, channel):
		ut = self.startTime
		then = time.gmtime(ut)
		since = then = time.strftime('%x %X', then)
		then = datetime.strptime(then, '%x %X')
		now = time.gmtime(time.time())
		now = time.strftime('%x %X', now)
		now = datetime.strptime(now, '%x %X')
		delta = now - then
		p = nick
		if self.getAccess(nick.lower()) < 1:
			return
		else:
			return "total runtime is : %s, or since %s" % (delta, since)
	
	def ily(self, nick, message, channel):
		if self.getAccess(nick.lower()) < 1:
			return
		else:
			return "%s i %s ^-^" % (nick, random.choice(["luv chu", "LOVES YOU", "<3 chu"]))
			
	def lvll(self, nick, message, channel):
		if self.getAccess(nick.lower()) < 2:
			return "I cant tell you ^-^"
		else:
			return "%s whitelisted users %s staff and %s owners ^-^" % (len(users), len(staff), len(owner))
	
	def help(self, nick, message, channel):
		if self.getAccess(nick.lower()) < 1:
			return "%s you need to be whitelisted in order to use me please ask a staff member ^-^" % nick
		else:
			return "Hai, %s im %s a chatbot ^-^" % (nick, "nyu")
			
	def df(self, nick, message, channel):
		args = message[3:]
		word, definition = args.split(" as", 1)
		word = word.lower()
		if len(word.split()) > 1:
			return "no phrases"
		if len(definition) > 0: #if there's a colon somewhere
			if word in dictionary:
					return "word %s already defined" % word
			else:
					dictionary[word] = json.dumps([definition, nick.lower()])
					print("[SAV] Saving Definitions..")
					f = open("definitions.txt", "w")
					for word in dictionary:
						definition, name = json.loads(dictionary[word])
						f.write(json.dumps([word, definition, nick.lower()])+"\n")
					f.close()
					return "done ^-^"
				
	def getdf(self, nick, message, channel):
		args = message[3:]
		if self.getAccess(nick.lower()) < 1:
			return
		else:
			word = args
			if args in dictionary:
				definition, name = json.loads(dictionary[word])
				return("" + word + " " " -" + definition + " *by* " "" + name + " ^-^")
			if not args in dictionary:
				return ("%s is not yet defined you can define it by saying %s df %s as meaning  ^-^" % (args, "nyu", args))
	
	def cdf(self, nick, message, channel):
		if self.getAccess(nick.lower()) < 1:
			return
		else:
			return "I have " + str(len(dictionary)) + " definitions ^-^"
		
	def rmdf(self, nick, message, channel):
		word = message[5:]
		if word in dictionary:
			definition, name = json.loads(dictionary[word])
			if name == nick.lower() or self.getAccess(nick.lower()) >= 2:
				del dictionary[word]
				print("[SAV] Saving Definitions..")
				f = open("definitions.txt", "w")
				for word in dictionary:
					definition, name = json.loads(dictionary[word])
					f.write(json.dumps([word, definition, name])+"\n")
				f.close()
				return "okies ^-^"
			else:
				return "%s you can not remove this define only masters or the person who defined the word may remove definitions ^^" % nick
		else:
			return "%s is not yet defined you can define it by typing nyu df %s: meaning" % (word, word)
	
	def glvl(self, nick, message, channel):
		args = message[7:]
		if args == "me": args = nick.lower()
		if self.getAccess(nick.lower()) < 1:
			return
		else:
			return "%s is level %s ^-^" % (args.title(), self.getAccess(args.lower()))
				
	def command_patterns(self):
			# COMMANDS
			return (
				self.ping('^hi', self.greet),
				self.ping('^dice', self.dice),
				self.ping('lock', self.lock),
				self.ping('unlock', self.unlock),
				self.ping('checklock', self.checklock),
				self.ping('say', self.say),
				self.ping('activate', self.aware),
				self.ping('sut', self.sut),
				self.ping('sl', self.sl),
				self.ping('lvl', self.lvl),
				self.ping('sd', self.sd),
				self.ping('wlcount', self.wlcount),
				self.ping('acc', self.wl),
				self.ping("staff", self.staff),
				self.ping('ut', self.ut),
				self.ping('<3', self.ily),
				self.ping('ily', self.ily),
				self.ping('level-list', self.lvll),
				self.ping('help', self.help),
				self.ping('df', self.df),
				self.ping('gd', self.getdf),
				self.ping('count-df', self.cdf),
				self.ping('rmdf', self.rmdf),
				self.ping('getlvl', self.glvl),
			)


host = 'irc.example.tld'
port = 6667
nick = 'tehircbot'

run_bot(GreeterBot, host, port, nick, ['#bots'])
